#pragma once

#include "ValueSpecification.h"

#include "ParameterableElement.h"

namespace uml {

ValueSpecification::ValueSpecification(const QString& umlType)
    : PackageableElement(umlType) {}

void ValueSpecification::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    TypedElement::fromJson(json, errorList);
    PackageableElement::fromJson(json, errorList);
}

void ValueSpecification::toJson(QJsonObject& json) {
    TypedElement::toJson(json);
    PackageableElement::toJson(json);
}

/// <summary>
/// booleanValue
    /// The query booleanValue() gives a single Boolean value when one can be computed.
/// </summary>
    /// <code>
    /// result = (null)
    /// </code>
bool ValueSpecification::booleanValue() const
{
    return false;
}

/// <summary>
/// integerValue
    /// The query integerValue() gives a single Integer value when one can be computed.
/// </summary>
    /// <code>
    /// result = (null)
    /// </code>
int ValueSpecification::integerValue() const
{
    return 0;
}

/// <summary>
/// isCompatibleWith
    /// The query isCompatibleWith() determines if this ValueSpecification is compatible
    /// with the specified ParameterableElement. This ValueSpecification is compatible
    /// with ParameterableElement p if the kind of this ValueSpecification is the same
    /// as or a subtype of the kind of p. Further, if p is a TypedElement, then the type
    /// of this ValueSpecification must be conformant with the type of p.
/// </summary>
    /// <code>
    /// result = (self.oclIsKindOf(p.oclType()) and (p.oclIsKindOf(TypedElement) implies 
    /// self.type.conformsTo(p.oclAsType(TypedElement).type)))
    /// </code>
bool ValueSpecification::isCompatibleWith(shared_ptr<ParameterableElement> p) const
{
    return false;
}

/// <summary>
/// isComputable
    /// The query isComputable() determines whether a value specification can be
    /// computed in a model. This operation cannot be fully defined in OCL. A conforming
    /// implementation is expected to deliver true for this operation for all
    /// ValueSpecifications that it can compute, and to compute all of those for which
    /// the operation is true. A conforming implementation is expected to be able to
    /// compute at least the value of all LiteralSpecifications.
/// </summary>
    /// <code>
    /// result = (false)
    /// </code>
bool ValueSpecification::isComputable() const
{
    return false;
}

/// <summary>
/// isNull
    /// The query isNull() returns true when it can be computed that the value is null.
/// </summary>
    /// <code>
    /// result = (false)
    /// </code>
bool ValueSpecification::isNull() const
{
    return false;
}

/// <summary>
/// realValue
    /// The query realValue() gives a single Real value when one can be computed.
/// </summary>
    /// <code>
    /// result = (null)
    /// </code>
double ValueSpecification::realValue() const
{
    return 0.0;
}

/// <summary>
/// stringValue
    /// The query stringValue() gives a single String value when one can be computed.
/// </summary>
    /// <code>
    /// result = (null)
    /// </code>
QString ValueSpecification::stringValue() const
{
    return "";
}

/// <summary>
/// unlimitedValue
    /// The query unlimitedValue() gives a single UnlimitedNatural value when one can be
    /// computed.
/// </summary>
    /// <code>
    /// result = (null)
    /// </code>
int ValueSpecification::unlimitedValue() const
{
    return 0;
}

} // namespace uml
